package com.zmn.oms.business.interfaces.orderstock;

import com.zmn.engstock.common.model.dro.EngineerStockItemDRO;
import com.zmn.engstock.common.model.dro.StockItemDRO;
import com.zmn.engstock.common.model.dro.stock.StockUsedOrderDetailDRO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.stock.DistributeMasterStockBO;
import com.zmn.oms.model.bo.stock.MasterStockQueryBO;
import com.zmn.oms.model.dto.orderstock.*;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.orderstock.OrderStockVO;
import com.zmn.oms.model.vo.orderstock.SpOrderStockVO;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 类描述：订单库存
 * @author heciqi
 * @date 2020/5/7 16:07
 */
public interface OrderStockBService {

    /**
     * 获取工程师库存
     *
     * @param curDate        日期
     * @param engineerId     工程师ID
     * @param productGroupCode 产品组CODE
     * @param productNum     产品数量
     * @param workId     工单id（用于是否排除本单已锁定库存）
     * @return
     */
    List<StockItemDRO> getStockByEngineerIdAndProductGroupId(String curDate, Integer engineerId, Integer productGroupCode, Integer productNum, Long workId);

    /**
     * 重新占用库存
     *
     * @param lockStockDTO
     * @throws OmsBaseException
     */
    void reLockEngStock(LockStockDTO lockStockDTO) throws OmsBaseException;

    /**
     * 释放库存
     *
     * @param releaseStockDTO
     * @throws OmsBaseException
     */
    void releaseStock(ReleaseStockDTO releaseStockDTO) throws OmsBaseException;

    /**
     * 释放库存
     *
     * @param orderId
     * @param workId
     * @throws OmsBaseException
     */
    void releaseStock(Long orderId, Long workId) throws OmsBaseException;

    /**
     * 动态库存试点工程师
     * @param masterId
     * @return
     */
    boolean isWhiteMasterId(Integer masterId);

    /**
     * 动态库存试点城市
     * @param cityId
     * @return true 是、false 否
     */
    boolean isWhiteWorkCity(Integer cityId);

    /**
     * 是否试点-全部条件
     * @return
     */
    boolean isWhiteByAllConditions(StockWhiteDTO stockWhiteDTO);

    /**
     * 是否占用过库存
     * @param workId
     * @param engineerId
     * @return
     * @throws OmsBaseException
     */
    boolean checkExitOrder(Long workId,Integer engineerId) throws OmsBaseException;

    /**
     * 占用库存
     * @param lockStockDTO
     * @throws OmsBaseException
     */
    void takeUpStock(LockStockDTO lockStockDTO) throws OmsBaseException;
    void takeUpStock(LockStockDTO lockStockDTO, OrderWork newestOrderWork) throws OmsBaseException;

    /**
     * 检查是否需要锁定库存
     *
     * @param checkLockStockDTO
     * @return
     * @throws OmsBaseException
     */
    boolean checkIsLockStock(CheckLockStockDTO checkLockStockDTO);

    /**
     * 获取库存检测锁定DTO
     *
     * @param orderWork
     * @return
     */
    CheckLockStockDTO getCheckLockStockDTO(OrderWork orderWork);

    /**
     * 释放库存限定跟单内容ids
     * @return
     */
    List<Integer> releaseStockRestrictTrackContentIds();

    /**
     * 可派单工程师
     * map.key 工程师id
     * map.value 工程师库存类型
     * @see com.zmn.oms.common.enums.MasterStockTypeEnum#OPTIMAL_STOCK
     * @return
     */
    Map<Integer, Integer> canDistributeMaster(DistributeMasterStockBO distributeMasterStockBO);

    /**
     * 库存是否过期
     * @param orderId
     * @param workId
     * @return true过期 false没过期
     */
    boolean isStockOverdue(Long orderId, Long workId) throws OmsBaseException;

    /**
     * 获取试点工程师集合
     * @return
     */
    Set<Integer> getStockMasterIdList();

    Map<Integer, List<StockItemDRO>> listMasterStock(MasterStockQueryBO masterStockQueryBO);

    /**
     * 获取指定工程师使用的订单库存详情
     * @param engineerId 工程师id
     * @return
     */
    List<StockUsedOrderDetailDRO> getStockUserOrderDetailByEngineerId(Integer engineerId);

    /**
     * 获取指定工程师在指定日期使用的订单库存详情
     *
     * @param engineerId 工程师id
     * @param startDate 查询日期-开始
     * @param endDate 查询日期-结束
     * @return
     */
    List<StockUsedOrderDetailDRO> getStockUserOrderDetailByQuery(Integer engineerId, String startDate, String endDate);

    /**
     * 校验服务时间是否可以交换
     * @param engineerId 工程师id
     * @param sourceOrderId 当前工单id
     * @param targetOrderId 交换工单id
     * @return
     */
    Boolean checkServTimeCanChang(Integer engineerId, Long sourceOrderId, Long targetOrderId);

    /**
     * 交换指定工程师的两个订单的服务时间
     *
     * @param engineerId 工程师id
     * @param sourceOrderId 当前工单id
     * @param targetOrderId 交换工单id
     * @param operator 操作人
     * @return
     */
    Boolean exChangeTwoOrderServTime(Integer engineerId, Long sourceOrderId, Long targetOrderId, String operator);
}
